



#include"mcu_soft_sccb.h"



////////////////// 下面的引脚操作接口用户定义。

/// <summary>
/// SCCB scl 引脚设置高电平
/// </summary>
/// <param name="device">SCCB 设备</param>
void SCCB_SCL_H(SCCBdevice* device) { mcu_set_io(device->scl, 1); }
/// <summary>
/// SCCB scl 引脚设置低电平
/// </summary>
/// <param name="device">SCCB 设备</param>
void SCCB_SCL_L(SCCBdevice* device) { mcu_set_io(device->scl, 0); }
/// <summary>
/// SCCB sda 引脚设置高电平
/// </summary>
/// <param name="device">SCCB 设备</param>
void SCCB_SDA_H(SCCBdevice* device) { mcu_set_io(device->scl, 1); }
/// <summary>
/// SCCB sda 引脚设置低电平
/// </summary>
/// <param name="device">SCCB 设备</param>
void SCCB_SDA_L(SCCBdevice* device) { mcu_set_io(device->scl, 0); }
/// <summary>
/// 读取SCCB sda 引脚电平
/// </summary>
/// <param name="device">SCCB 设备</param>
/// <returns>0低电平，1高电平</returns>
int SCCB_SDA_READ(SCCBdevice* device) { return mcu_read_io(device->sda); }

/// <summary>
/// SDA引脚设置输出模式
/// </summary>
/// <param name="device">SCCB 设备</param>
void Soft_SCCB_Output(SCCBdevice* device) { mcu_set_io_out(device->sda); }

/// <summary>
/// SDA引脚设置输入模式
/// </summary>
/// <param name="device">SCCB 设备</param>
void Soft_SCCB_Input(SCCBdevice* device) { mcu_set_io_in(device->sda); }
//


// 上面是硬件部分。

#define SCCB_DELAY_TIME 50 //延时倍数
/**
 * @brief SCCB延时
 * @param  无
 * @return 无
 */
void SCCB_Delay(int time)
{
	unsigned int i = time * 1; // 用户根据自己的MCU时钟进行设置倍数
	while (i--)
	{
		;
	}
}

//初始化SCCB接口
//CHECK OK
void SCCB_Init(SCCBdevice* device)
{

	Soft_SCCB_Output(device);
}
//SCCB起始信号
//当时钟为高的时候,数据线的高到低,为SCCB起始信号
//在激活状态下,SDA和SCL均为低电平
void SCCB_Start(SCCBdevice* device)
{
	SCCB_SDA_H(device);     //数据线高电平	   
	SCCB_SCL_H(device);	    //在时钟线高的时候数据线由高至低
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SDA_L(device);
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SCL_L(device);	    //数据线恢复低电平，单操作函数必要	  
}
//SCCB停止信号
//当时钟为高的时候,数据线的低到高,为SCCB停止信号
//空闲状况下,SDA,SCL均为高电平
void SCCB_Stop(SCCBdevice* device)
{
	SCCB_SDA_L(device);
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SCL_H(device);
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SDA_H(device);
	SCCB_Delay(SCCB_DELAY_TIME);
}
//产生NA信号
void SCCB_No_Ack(SCCBdevice* device)
{
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SDA_H(device);
	SCCB_SCL_H(device);
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SCL_L(device);
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SDA_L(device);
	SCCB_Delay(SCCB_DELAY_TIME);
}
//SCCB,写入一个字节
//返回值:0,成功;1,失败. 
unt8 SCCB_WR_Byte(SCCBdevice* device,unt8 dat)
{
	unt8 j, res;
	for (j = 0; j < 8; j++) //循环8次发送数据
	{
		if (dat & 0x80)SCCB_SDA_H(device);
		else SCCB_SDA_L(device);
		dat <<= 1;
		SCCB_Delay(SCCB_DELAY_TIME);
		SCCB_SCL_H(device);
		SCCB_Delay(SCCB_DELAY_TIME);
		SCCB_SCL_L(device);
	}
	Soft_SCCB_Input(device);		//设置SDA为输入 
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_SCL_H(device);			//接收第九位,以判断是否发送成功
	SCCB_Delay(SCCB_DELAY_TIME);
	if (SCCB_SDA_READ(device))res = 1;  //SDA=1发送失败，返回1
	else res = 0;         //SDA=0发送成功，返回0
	SCCB_SCL_L(device);
	Soft_SCCB_Output(device);		//设置SDA为输出    
	return res;
}
//SCCB 读取一个字节
//在SCL的上升沿,数据锁存
//返回值:读到的数据
unt8 SCCB_RD_Byte(SCCBdevice* device)
{
	unt8 temp = 0, j;
	Soft_SCCB_Input(device);		//设置SDA为输入  
	for (j = 8; j > 0; j--) 	//循环8次接收数据
	{
		SCCB_Delay(SCCB_DELAY_TIME);
		SCCB_SCL_H(device);
		temp = temp << 1;
		if (SCCB_SDA_READ(device))temp++;
		SCCB_Delay(SCCB_DELAY_TIME);
		SCCB_SCL_L(device);
	}
	Soft_SCCB_Output(device);		//设置SDA为输出    
	return temp;
}
//写寄存器
//返回值:0,成功;1,失败.
unt8 SCCB_WR_Reg(SCCBdevice* device,unt8 reg, unt8 data)
{
	unt8 res = 0;
	SCCB_Start(device); 					//启动SCCB传输
	if (SCCB_WR_Byte(device,device->SCCB_ID))res = 1;	//写器件ID	  
	SCCB_Delay(SCCB_DELAY_TIME);
	if (SCCB_WR_Byte(device,reg))res = 1;		//写寄存器地址	  
	SCCB_Delay(SCCB_DELAY_TIME);
	if (SCCB_WR_Byte(device,data))res = 1; 	//写数据	 
	SCCB_Stop(device);
	return	res;
}
//读寄存器
//返回值:读到的寄存器值
unt8 SCCB_RD_Reg(SCCBdevice* device,unt8 reg)
{
	unt8 val = 0;
	SCCB_Start(device); 				//启动SCCB传输
	SCCB_WR_Byte(device,device->SCCB_ID);		//写器件ID	  
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_WR_Byte(device,reg);			//写寄存器地址	  
	SCCB_Delay(SCCB_DELAY_TIME);
	SCCB_Stop(device);
	SCCB_Delay(SCCB_DELAY_TIME);
	//设置寄存器地址后，才是读
	SCCB_Start(device);
	SCCB_WR_Byte(device,device->SCCB_ID | 0X01);	//发送读命令	  
	SCCB_Delay(SCCB_DELAY_TIME);
	val = SCCB_RD_Byte(device);		 	//读取数据
	SCCB_No_Ack(device);
	SCCB_Stop(device);
	return val;
}



















